#include "stm32f10x.h"
#include "bsp_spi.h"
#include <stdio.h>  

//这个得注意些，得把无关的头文件去除

uint32_t SPITime_out=0;   //设置超时时间

/**
*	@brief	SPI初始化函数(1.初始化目标引脚及时钟 2.使能SPI时钟 3.配置SPI外设的相关参数 4.最终开启SPI外设)
*			为了兼容SI4438和RA2这里的SPI时钟为64分频
*	@param	无
*	@retval 无
*/
void SpiInit( void )
{
    SPI_InitTypeDef 	SPI_InitStructure;    //SPI初始化结构体
    GPIO_InitTypeDef 	GPIO_InitStructure;   //GPIO初始化结构体

    //开启相关时钟    (把要变得都用宏先定义)
    _SPI_CLOCK_FUN	(_SPI_CLOCK_CMD,ENABLE);  //SPI时钟
    _SPI_SCK_CLOCK_FUN(_SPI_SCK_CLOCK_CMD|_SPI_MISO_CLOCK_CMD|_SPI_MOSI_CLOCK_CMD,ENABLE);//开启SPI引脚时钟

    //初始化目标引脚
    //配置SPI的SCK引脚,MISO引脚,MOSI引脚
    GPIO_InitStructure.GPIO_Pin=_SPI_SCK_PIN|_SPI_MISO_PIN|_SPI_MOSI_PIN;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;
    GPIO_Init(_SPI_SCK_PORT,&GPIO_InitStructure);
		GPIO_SetBits( _SPI_MISO_PORT, _SPI_MISO_PIN ); //将其电平拉高
		GPIO_SetBits( _SPI_MOSI_PORT, _SPI_MOSI_PIN ); //将其电平拉高
		RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE );

    //SPI配置模式  (这个得根据具体的芯片来配置)
    SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex; //两线全双工
    SPI_InitStructure.SPI_Mode=SPI_Mode_Master;   //主机模式
    SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;   //数据长度为8位
    SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;         //0
    SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;        //0  即模式1
    SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;           //CS引脚由软件控制
    SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_64;   //64分频  SPI1挂在APB2总线上(分频后即72MHz/64=1.125MHz)
    SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;   //最高位先发
    SPI_InitStructure.SPI_CRCPolynomial=7;             //这个值其实无效
    SPI_Init(_SPIx,&SPI_InitStructure);           //

    //最后一步,使能SPI
    SPI_Cmd(_SPIx,ENABLE);
}

//一般流程是写一个字节,等待一定的时序,然后读，之后写。。。最后读

/**
 *   @brief	使用SPI发送一个字节的数据
 *	 @param	byte要发送的数据
 *	 @retval 返回收到的数据
 */
uint8_t SpiInOut( uint8_t outData )  //写一个同时读一个(突出的是写)
{
    SPITime_out=SPI_FLAG_TIMEOUT;   //设置超时时间
    //写之前得确保发送缓冲为空
    while(SPI_I2S_GetFlagStatus(_SPIx,SPI_I2S_FLAG_TXE)==RESET)
    {
        //但又不能一直在此等(一定次数后得退出)
        if((SPITime_out--)==0)
        {
            return 0;
        }
    }
    //空了之后,将要发送的数据写入缓冲区
    SPI_I2S_SendData(_SPIx,outData);

    //接下来就该读了
    SPITime_out=SPI_FLAG_TIMEOUT;
    //等待接收缓冲区非空,RXNE事件
    while(SPI_I2S_GetFlagStatus(_SPIx,SPI_I2S_FLAG_RXNE)==RESET)
    {
        if((SPITime_out--)==0)
        {
            return 0;
        }
    }
    //读取数据寄存器,获取接收缓冲区数据
    return	SPI_I2S_ReceiveData(_SPIx);
}




